package com.wyits;


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class MakePartSqlTool {
    /**
     *
     * 整体思路：读取配置文件获取SQL基本语句
     * 在建表时只创建一个分区，其余通过增加分区的形式补齐
     * 根据传入的partFlag判断SQL替换级别
     * SQL样例：PARTITION #TABLENAME#_#PARTFLAG##YEAR# VALUES LESS THAN (TO_DATE ('#YEAR#-#MONTH#-#DAY#', 'yyyy-mm-dd'))
     * 需要替换的变量：
     *      表名：#TABLENAME#
     *      分区键：#PARTFLAG#
     *      分区名称中年标志位：#YEARPARTNAME#
     *      分区名称中月标志位：#MONTHPARTNAME#
     *      分区名称中天标志位：#DAYPARTNAME#
     *      分区年份：#YEAR#
     *      分区月份：#MONTH#
     *      分区日：#DAY#
     *
     */
    private static String configPath  = null ;
    private static String tableName   = null ;
    private static String inputFlag   = null ;
    private static String partColName = null ;

    private static final String tableNameKey            =  "#TABLENAME#"      ;
    private static final String partitionColKey         =  "#PARTFLAG#"       ;
    private static final String partitionNameYearKey    =  "#YEARPARTNAME#"   ;
    private static final String partitionNameMonthKey   =  "#MONTHPARTNAME#"  ;
    private static final String partitionNameDayKey     =  "#DAYPARTNAME#"    ;
    private static final String partitionRuleYearKey    =  "#YEAR#"           ;
    private static final String partitionRuleMonthKey   =  "#MONTH#"          ;
    private static final String partitionRuleDayKey     =  "#DAY#"            ;


    private static final String create_table_partition_sql_key     =  "create_table_partition_sql"   ;
    private static final String append_table_partition_sql_key     =  "append_table_partition_sql"   ;
    private static final String start_date_key                     =  "start_date"                   ;
    private static final String end_date_sql_key                   =  "end_date"                     ;
    private static final String dateFrmat                          =  "yyyy-MM-dd"                   ;

    private static final String DAY_FLAG                     =  "D"  ;
    private static final String MONTH_FLAG                   =  "M"  ;
    private static final String YEAR_FLAG                    =  "Y"  ;

    private static String create_table_partition_sql_value     =  ""  ;
    private static String append_table_partition_sql_value     =  ""  ;
    private static String start_date_value                     =  ""  ;
    private static String end_date_value                       =  ""  ;

    private static Date start_date                     =  null  ;
    private static Date end_date                       =  null  ;


    private static HashMap<String, String> parmHashMap = new HashMap<String, String>();

    public static void makeMap(
            String inputTableNameKey           ,
            String inputPartitionColKey        ,
            String inputPartitionNameYearKey   ,
            String inputPartitionNameMonthKey  ,
            String inputPartitionNameDayKey    ,
            String inputPartitionRuleYearKey   ,
            String inputPartitionRuleMonthKey  ,
            String inputPartitionRuleDayKey
    ) {
        parmHashMap.clear();
        parmHashMap.put(tableNameKey           , inputTableNameKey          );
        parmHashMap.put(partitionColKey        , inputPartitionColKey       );
        parmHashMap.put(partitionNameYearKey   , inputPartitionNameYearKey  );
        parmHashMap.put(partitionNameMonthKey  , inputPartitionNameMonthKey );
        parmHashMap.put(partitionNameDayKey    , inputPartitionNameDayKey   );
        parmHashMap.put(partitionRuleYearKey   , inputPartitionRuleYearKey  );
        parmHashMap.put(partitionRuleMonthKey  , inputPartitionRuleMonthKey );
        parmHashMap.put(partitionRuleDayKey    , inputPartitionRuleDayKey   );
    }

    public static String makeSingleSql(String modSql) {
        //PARTITION #TABLENAME#_#PARTFLAG##YEAR# VALUES LESS THAN (TO_DATE ('#YEAR#-#MONTH#-#DAY#', 'yyyy-mm-dd'))
        String outStr = modSql;
        for (Map.Entry<String, String> resEntry : parmHashMap.entrySet()) {
            outStr = outStr.replaceAll(resEntry.getKey(), resEntry.getValue());
        }
        return outStr;
    }


    public static void getConfig() throws IOException {
        FileReader fileReader = new FileReader(configPath);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        Properties properties = new Properties();
        properties.load(bufferedReader);
        create_table_partition_sql_value = properties.getProperty(create_table_partition_sql_key);
        append_table_partition_sql_value = properties.getProperty(append_table_partition_sql_key);
        start_date_value                 = properties.getProperty(start_date_key                );
        end_date_value                   = properties.getProperty(end_date_sql_key              );
    }

    public static void getDateLimit() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFrmat);
        try {
            start_date = simpleDateFormat.parse(start_date_value);
            end_date   = simpleDateFormat.parse(end_date_value);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    public static String getDoubleStr(int inputNum) {
        String numStr = String.valueOf(inputNum);
        if (numStr.length() == 1) {
            numStr = "0" + numStr;
        }
        return numStr;
    }

    public static void packPartSqlMap() {
        Calendar beginCal = Calendar.getInstance();
        beginCal.setTime(start_date);
        int beginCalDay   = beginCal.get(Calendar.DATE);
        int beginCalMonth = beginCal.get(Calendar.MONTH)+1;
        int beginCalYear  = beginCal.get(Calendar.YEAR);
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(end_date);
        System.out.println("PARTITION BY RANGE ("+partColName+")");
        System.out.println("(");
        if (DAY_FLAG.equals(inputFlag)) {
            makeMap(tableName,
                    partColName,
                    getDoubleStr(beginCalYear),
                    getDoubleStr(beginCalMonth),
                    getDoubleStr(beginCalDay),
                    getDoubleStr(beginCalYear),
                    getDoubleStr(beginCalMonth),
                    getDoubleStr(beginCalDay));
            System.out.println(makeSingleSql(create_table_partition_sql_value));
            System.out.println(");");
            while (end_date.after(beginCal.getTime())) {
                beginCal.add(Calendar.DAY_OF_MONTH, 1);
                makeMap(tableName,
                        partColName,
                        getDoubleStr(beginCal.get(Calendar.YEAR)),
                        getDoubleStr(beginCal.get(Calendar.MONTH)+1),
                        getDoubleStr(beginCal.get(Calendar.DATE)),
                        getDoubleStr(beginCal.get(Calendar.YEAR)),
                        getDoubleStr(beginCal.get(Calendar.MONTH)+1),
                        getDoubleStr(beginCal.get(Calendar.DATE)));
                System.out.println(makeSingleSql(append_table_partition_sql_value)+";");
            }
        }
        if (MONTH_FLAG.equals(inputFlag)) {
            makeMap(tableName,
                    partColName,
                    getDoubleStr(beginCalYear),
                    getDoubleStr(beginCalMonth),
                    "",
                    getDoubleStr(beginCalYear),
                    getDoubleStr(beginCalMonth),
                    "01");
            System.out.println(makeSingleSql(create_table_partition_sql_value));
            System.out.println(");");
            while (end_date.after(beginCal.getTime())) {
                beginCal.add(Calendar.MONTH, 1);
                makeMap(tableName,
                        partColName,
                        getDoubleStr(beginCal.get(Calendar.YEAR)),
                        getDoubleStr(beginCal.get(Calendar.MONTH)+1),
                        "",
                        getDoubleStr(beginCal.get(Calendar.YEAR)),
                        getDoubleStr(beginCal.get(Calendar.MONTH)+1),
                        "01");
                System.out.println(makeSingleSql(append_table_partition_sql_value)+";");
            }
        }

        if (YEAR_FLAG.equals(inputFlag)) {
            makeMap(tableName,
                    partColName,
                    getDoubleStr(beginCalYear),
                    "",
                    "",
                    getDoubleStr(beginCalYear),
                    "01",
                    "01");
            System.out.println(makeSingleSql(create_table_partition_sql_value));
            System.out.println(");");
            while (end_date.after(beginCal.getTime())) {
                beginCal.add(Calendar.YEAR, 1);
                makeMap(tableName,
                        partColName,
                        getDoubleStr(beginCal.get(Calendar.YEAR)),
                        "01",
                        "",
                        getDoubleStr(beginCal.get(Calendar.YEAR)),
                        "01",
                        "01");
                System.out.println(makeSingleSql(append_table_partition_sql_value)+";");
            }
        }
    }
    /**
     *
     * @param args
     */
    public static void main(String[] args) throws IOException {
        if (args != null && args.length<=4) {
            configPath  = args[0];
            tableName   = args[1];
            inputFlag   = args[2];
            partColName = args[3];
        } else {
            throw new RuntimeException("args not enough!");
        }
        /*configPath  = "E:\\nightwork\\210922-datetool\\part-test-v0.4\\part-test\\sqlconfig\\sqlConfig.properties" ;
        tableName   = "FP_ACCT" ;
        inputFlag   = "Y" ;
        partColName = "TRAN_DATE" ;*/
        getConfig();
        getDateLimit();
        packPartSqlMap();
    }
}
